#pragma once

#include <iostream>
#include <string>
#include <pthread.h>

enum class Status
{
    NEW = 0, // 新建
    RUNNING, // 运行中
    EXIT // 已退出
};

// 参数、返回值为 void 的函数类型
typedef void (*func_t)(void*);

class Thread
{
public:
    Thread(int num = 0, func_t func = nullptr, void* args = nullptr)
        :_tid(0), _status(Status::NEW), _func(func), _args(args)
    {
        // 根据编号写入名字
        char name[128];
        snprintf(name, sizeof name, "thread-%d", num);
        _name = name;
    }

    ~Thread()
    {}

    // 获取 ID
    pthread_t getTID() const
    {
        return _tid;
    }

    // 获取线程名
    std::string getName() const
    {
        return _name;
    }

    // 获取状态
    Status getStatus() const
    {
        return _status;
    }

    // 回调方法
    static void* runHelper(void* args)
    {
        Thread* myThis = static_cast<Thread*>(args);

        // 很简单，回调用户传进来的 func 函数即可
        myThis->_func(myThis->_args);
        return nullptr;
    }

    // 启动线程
    void run()
    {
        int ret = pthread_create(&_tid, nullptr, runHelper, this);
        if(ret != 0)
        {
            std::cerr << "create thread fail!" << std::endl;
            exit(1); // 创建线程失败，直接退出
        }
        _status =  Status::RUNNING; // 更改状态为 运行中
    }

    // 线程等待
    void join()
    {
        int ret = pthread_join(_tid, nullptr);
        if(ret != 0)
        {
            std::cerr << "thread join fail!" << std::endl;
            exit(1); // 等待失败，直接退出
        }
        _status = Status::EXIT; // 更改状态为 退出
    }

private:
    pthread_t _tid; // 线程 ID
    std::string _name; // 线程名
    Status _status; // 线程状态
    func_t _func; // 线程回调函数
    void* _args; // 传递给回调函数的参数
};
